<template>
  <div class="file-list">
    <!-- 工具栏 -->
    <div class="file-toolbar">
      <div class="toolbar-left">
        <a-input-search v-model:value="searchKeyword" placeholder="搜索文件名或描述" style="width: 300px" @search="handleSearch" @pressEnter="handleSearch" />
        <a-button @click="handleRefresh" :loading="loading">
          <template #icon><reload-outlined /></template>
          刷新
        </a-button>
      </div>
      <div class="toolbar-right">
        <a-select v-model:value="sortBy" style="width: 120px; margin-right: 8px" @change="handleSortChange">
          <a-select-option value="created_at">上传时间</a-select-option>
          <a-select-option value="original_name">文件名</a-select-option>
          <a-select-option value="file_size">文件大小</a-select-option>
          <a-select-option value="uploader_username">上传者</a-select-option>
        </a-select>
        <a-select v-model:value="sortOrder" style="width: 80px; margin-right: 8px" @change="handleSortChange">
          <a-select-option value="DESC">降序</a-select-option>
          <a-select-option value="ASC">升序</a-select-option>
        </a-select>
        <a-button @click="toggleViewMode">
          <template #icon>
            <appstore-outlined v-if="viewMode === 'list'" />
            <bars-outlined v-else />
          </template>
          {{ viewMode === 'list' ? '网格' : '列表' }}
        </a-button>
      </div>
    </div>

    <!-- 批量操作栏 -->
    <div v-if="isAdmin && files.length > 0" class="batch-actions-bar">
      <div class="batch-actions-left">
        <a-checkbox :checked="isAllSelected" :indeterminate="isIndeterminate" @change="handleSelectAll"> 全选 </a-checkbox>
        <span v-if="selectedFiles.length > 0" class="selected-count"> 已选择 {{ selectedFiles.length }} 个文件 </span>
      </div>
      <div v-if="selectedFiles.length > 0" class="batch-actions-right">
        <a-button danger @click="handleBatchDelete">
          <template #icon><delete-outlined /></template>
          批量删除
        </a-button>
        <a-button @click="handleClearSelection"> 取消选择 </a-button>
      </div>
    </div>

    <!-- 文件列表 -->
    <div v-if="loading" class="loading-container">
      <a-spin size="large" />
    </div>

    <div v-else-if="files.length === 0" class="empty-container">
      <file-outlined class="empty-icon" />
      <p>暂无文件</p>
    </div>

    <div v-else class="file-container" :class="viewMode">
      <div v-for="file in files" :key="file.id" class="file-item" :class="{ selected: isFileSelected(file.id) }" @click="handleFileClick(file)">
        <!-- 多选复选框（仅管理员可见） -->
        <div v-if="isAdmin" class="file-checkbox" @click.stop>
          <a-checkbox :checked="isFileSelected(file.id)" @change="handleFileSelect(file.id)" />
        </div>
        <!-- 文件分类标签 -->
        <div v-if="file.categoryName" class="file-category" @click.stop>
          <folder-outlined />
          <span>{{ file.categoryName }}</span>
        </div>
        <div class="file-icon" :class="getFileTypeClass(file.mimeType)">
          <component :is="getFileIcon(file.mimeType)" />
        </div>
        <div class="file-info">
          <div class="file-name" :title="file.originalName">
            {{ file.originalName }}
          </div>
          <div class="file-meta">
            <span class="file-size">{{ formatFileSize(file.fileSize) }}</span>
            <span class="file-date">{{ formatDate(file.createdAt) }}</span>
            <span v-if="file.uploaderUsername" class="file-uploader"> 上传者：{{ file.uploaderUsername }} </span>
          </div>
          <div v-if="file.description" class="file-description">
            {{ file.description }}
          </div>
          <!-- 列表视图中显示分类 -->
          <div v-if="file.categoryName && viewMode === 'list'" class="file-category-inline">
            <folder-outlined />
            <span>{{ file.categoryName }}</span>
          </div>
        </div>
        <div class="file-actions" @click.stop>
          <!-- 网格视图：横向操作按钮 -->
          <div v-if="viewMode === 'grid'" class="action-buttons-grid">
            <a-button type="text" size="small" @click="handleDownload(file)" title="下载">
              <template #icon><download-outlined /></template>
            </a-button>
            <!-- <a-button type="text" size="small" @click="handlePreview(file)" title="预览">
              <template #icon><eye-outlined /></template>
            </a-button> -->
            <!-- <a-button type="text" size="small" @click="handleShowInfo(file)" title="详情">
              <template #icon><info-circle-outlined /></template>
            </a-button> -->
            <a-button v-if="isAdmin" type="text" size="small" danger @click="handleDelete(file)" title="删除">
              <template #icon><delete-outlined /></template>
            </a-button>
          </div>

          <!-- 列表视图：下拉菜单 -->
          <a-dropdown v-else :trigger="['click']">
            <a-button type="text" size="small">
              <template #icon><more-outlined /></template>
            </a-button>
            <template #overlay>
              <a-menu>
                <a-menu-item key="download" @click="handleDownload(file)">
                  <template #icon><download-outlined /></template>
                  下载
                </a-menu-item>
                <!-- <a-menu-item key="preview" @click="handlePreview(file)">
                  <template #icon><eye-outlined /></template>
                  预览
                </a-menu-item>
                <a-menu-item key="info" @click="handleShowInfo(file)">
                  <template #icon><info-circle-outlined /></template>
                  详情
                </a-menu-item> -->
                <a-menu-item v-if="isAdmin" key="delete" danger @click="handleDelete(file)">
                  <template #icon><delete-outlined /></template>
                  删除
                </a-menu-item>
              </a-menu>
            </template>
          </a-dropdown>
        </div>
      </div>
    </div>

    <!-- 分页 -->
    <div v-if="pagination.totalPages > 1" class="pagination-container">
      <a-pagination
        v-model:current="pagination.page"
        v-model:page-size="pagination.limit"
        :total="pagination.total"
        :show-size-changer="true"
        :show-quick-jumper="true"
        :show-total="(total, range) => `第 ${range[0]}-${range[1]} 条，共 ${total} 条`"
        @change="handlePageChange"
        @show-size-change="handlePageSizeChange"
      />
    </div>

    <!-- 文件详情模态框 -->
    <a-modal v-model:open="infoModalVisible" title="文件详情" :footer="null" width="600px">
      <div v-if="selectedFile" class="file-detail">
        <div class="detail-row">
          <span class="detail-label">文件名：</span>
          <span class="detail-value">{{ selectedFile.originalName }}</span>
        </div>
        <div class="detail-row">
          <span class="detail-label">文件大小：</span>
          <span class="detail-value">{{ formatFileSize(selectedFile.fileSize) }}</span>
        </div>
        <div class="detail-row">
          <span class="detail-label">文件类型：</span>
          <span class="detail-value">{{ selectedFile.mimeType }}</span>
        </div>
        <div class="detail-row">
          <span class="detail-label">分类：</span>
          <span class="detail-value">{{ selectedFile.categoryName || '未分类' }}</span>
        </div>
        <div class="detail-row">
          <span class="detail-label">上传者：</span>
          <span class="detail-value">{{ selectedFile.uploaderUsername || '未知' }}</span>
        </div>
        <div class="detail-row">
          <span class="detail-label">上传时间：</span>
          <span class="detail-value">{{ formatDate(selectedFile.createdAt) }}</span>
        </div>
        <div v-if="selectedFile.description" class="detail-row">
          <span class="detail-label">描述：</span>
          <span class="detail-value">{{ selectedFile.description }}</span>
        </div>
        <div class="detail-actions">
          <a-button type="primary" @click="handleDownload(selectedFile)">
            <template #icon><download-outlined /></template>
            下载文件
          </a-button>
          <a-button @click="handlePreview(selectedFile)">
            <template #icon><eye-outlined /></template>
            预览文件
          </a-button>
        </div>
      </div>
    </a-modal>

    <!-- 文件预览组件 -->
    <file-preview v-model="previewModalVisible" :file="previewFile" />
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { message, Modal } from 'ant-design-vue'
import {
  ReloadOutlined,
  AppstoreOutlined,
  BarsOutlined,
  MoreOutlined,
  DownloadOutlined,
  EyeOutlined,
  InfoCircleOutlined,
  DeleteOutlined,
  FolderOutlined,
  FileOutlined,
  FileImageOutlined,
  FilePdfOutlined,
  FileWordOutlined,
  FileExcelOutlined,
  FilePptOutlined,
  FileZipOutlined,
  VideoCameraOutlined,
  AudioOutlined
} from '@ant-design/icons-vue'
import { useFileStorageStore } from '@/stores/fileStorage'
import { useUserStore } from '@/stores/user'
import FilePreview from './FilePreview.vue'

// 使用store
const fileStorageStore = useFileStorageStore()
const userStore = useUserStore()

// 响应式数据
const searchKeyword = ref('')
const sortBy = ref('created_at')
const sortOrder = ref('DESC')
const viewMode = ref('grid') // 默认使用网格布局
const infoModalVisible = ref(false)
const selectedFile = ref(null)
const previewModalVisible = ref(false)
const previewFile = ref(null)
const selectedFiles = ref([]) // 多选的文件ID列表

// 计算属性
const files = computed(() => fileStorageStore.files)
const loading = computed(() => fileStorageStore.loading)
const pagination = computed(() => fileStorageStore.pagination)
const isAdmin = computed(() => {
  return userStore.isAuthenticated && (userStore.user?.username === 'woaichitudouo' || userStore.user?.username === 'woaichitudou')
})

// 是否全选
const isAllSelected = computed(() => {
  return files.value.length > 0 && selectedFiles.value.length === files.value.length
})

// 是否部分选中
const isIndeterminate = computed(() => {
  return selectedFiles.value.length > 0 && selectedFiles.value.length < files.value.length
})

// 监听搜索关键词变化
watch(searchKeyword, (newValue) => {
  if (newValue === '') {
    handleSearch()
  }
})

// 方法
const handleSearch = async () => {
  await fileStorageStore.searchFiles(searchKeyword.value)
}

const handleRefresh = async () => {
  await fileStorageStore.loadFiles()
}

const handleSortChange = async () => {
  await fileStorageStore.loadFiles({
    sortBy: sortBy.value,
    sortOrder: sortOrder.value
  })
}

const toggleViewMode = () => {
  viewMode.value = viewMode.value === 'list' ? 'grid' : 'list'
}

const handleFileClick = (file) => {
  // 默认点击预览文件
  handlePreview(file)
}

const handleDownload = async (file) => {
  try {
    await fileStorageStore.downloadFileData(file)
    message.success('文件下载开始')
  } catch (error) {
    message.error('文件下载失败')
  }
}

const handlePreview = (file) => {
  // 使用新的预览组件
  previewFile.value = file
  previewModalVisible.value = true
}

const handleShowInfo = (file) => {
  selectedFile.value = file
  infoModalVisible.value = true
}

const handleDelete = (file) => {
  Modal.confirm({
    title: '确认删除',
    content: `确定要删除文件"${file.originalName}"吗？此操作不可恢复。`,
    okText: '确定',
    cancelText: '取消',
    onOk: async () => {
      try {
        await fileStorageStore.deleteFileData(file.id)
        message.success('文件删除成功')
      } catch (error) {
        message.error('文件删除失败')
      }
    }
  })
}

const handlePageChange = async (page) => {
  await fileStorageStore.changePage(page)
}

const handlePageSizeChange = async (current, size) => {
  pagination.value.limit = size
  await fileStorageStore.loadFiles()
}

const getFileIcon = (mimeType) => {
  const type = mimeType?.toLowerCase() || ''

  if (type.includes('image')) {
    return FileImageOutlined
  } else if (type.includes('video')) {
    return VideoCameraOutlined
  } else if (type.includes('audio')) {
    return AudioOutlined
  } else if (type.includes('pdf')) {
    return FilePdfOutlined
  } else if (type.includes('word') || type.includes('doc')) {
    return FileWordOutlined
  } else if (type.includes('excel') || type.includes('xls')) {
    return FileExcelOutlined
  } else if (type.includes('powerpoint') || type.includes('ppt')) {
    return FilePptOutlined
  } else if (type.includes('zip') || type.includes('rar') || type.includes('7z')) {
    return FileZipOutlined
  } else {
    return FileOutlined
  }
}

// 获取文件类型颜色类名
const getFileTypeClass = (mimeType) => {
  const type = mimeType?.toLowerCase() || ''

  if (type.includes('image')) {
    return 'file-type-image'
  } else if (type.includes('video')) {
    return 'file-type-video'
  } else if (type.includes('audio')) {
    return 'file-type-audio'
  } else if (type.includes('pdf')) {
    return 'file-type-pdf'
  } else if (type.includes('word') || type.includes('doc')) {
    return 'file-type-word'
  } else if (type.includes('excel') || type.includes('xls')) {
    return 'file-type-excel'
  } else if (type.includes('powerpoint') || type.includes('ppt')) {
    return 'file-type-ppt'
  } else if (type.includes('zip') || type.includes('rar') || type.includes('7z')) {
    return 'file-type-zip'
  } else if (type.includes('text')) {
    return 'file-type-text'
  } else {
    return 'file-type-default'
  }
}

const formatFileSize = (bytes) => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

const formatDate = (dateString) => {
  const date = new Date(dateString)
  return date.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  })
}

// 多选相关方法
const isFileSelected = (fileId) => {
  return selectedFiles.value.includes(fileId)
}

const handleFileSelect = (fileId) => {
  const index = selectedFiles.value.indexOf(fileId)
  if (index > -1) {
    selectedFiles.value.splice(index, 1)
  } else {
    selectedFiles.value.push(fileId)
  }
}

const handleSelectAll = (e) => {
  if (e.target.checked) {
    selectedFiles.value = files.value.map((file) => file.id)
  } else {
    selectedFiles.value = []
  }
}

const handleClearSelection = () => {
  selectedFiles.value = []
}

const handleBatchDelete = () => {
  if (selectedFiles.value.length === 0) {
    message.warning('请先选择要删除的文件')
    return
  }

  Modal.confirm({
    title: '批量删除确认',
    content: `确定要删除选中的 ${selectedFiles.value.length} 个文件吗？此操作不可恢复。`,
    okText: '确定',
    okType: 'danger',
    cancelText: '取消',
    onOk: async () => {
      try {
        // 批量删除文件
        const deletePromises = selectedFiles.value.map((fileId) => fileStorageStore.deleteFileData(fileId))
        await Promise.all(deletePromises)

        message.success(`成功删除 ${selectedFiles.value.length} 个文件`)
        selectedFiles.value = []

        // 重新加载文件列表
        await fileStorageStore.loadFiles()
      } catch (error) {
        console.error('批量删除失败:', error)
        message.error('批量删除失败，请重试')
      }
    }
  })
}

// 监听文件列表变化，清空无效的选中项
watch(files, () => {
  const validFileIds = files.value.map((file) => file.id)
  selectedFiles.value = selectedFiles.value.filter((id) => validFileIds.includes(id))
})
</script>

<style scoped>
.file-list {
  background: #fff;
  border-radius: 8px;
  padding: 16px;
  padding-bottom: 60px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.file-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid #f0f0f0;
}

.batch-actions-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  padding: 12px 16px;
  background: #f5f7fa;
  border-radius: 4px;
  border: 1px solid #e8eaec;
}

.batch-actions-left {
  display: flex;
  align-items: center;
  gap: 16px;
}

.selected-count {
  color: #1890ff;
  font-size: 14px;
  font-weight: 500;
}

.batch-actions-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

.toolbar-left {
  display: flex;
  align-items: center;
  gap: 12px;
}

.toolbar-right {
  display: flex;
  align-items: center;
}

.loading-container,
.empty-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 0;
  color: #8c8c8c;
}

.empty-icon {
  font-size: 48px;
  margin-bottom: 16px;
  color: #d9d9d9;
}

.file-container {
  min-height: 200px;
}

.file-container.list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.file-container.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 20px;
}

.file-item.selected {
  background: #e6f7ff;
  border-color: #e7eff7;
}

.file-checkbox {
  margin-right: 12px;
  flex-shrink: 0;
}

.file-container.grid .file-item {
  flex-direction: column;
  text-align: center;
  padding: 24px 20px;
  position: relative;
  border: none;
  transition: none;
}

.file-container.grid .file-item:hover {
  border: none;
}

.file-container.grid .file-item.selected {
  background: #f8f9fa;
}

.file-container.grid .file-checkbox {
  position: absolute;
  top: 10px;
  left: 10px;
  margin-right: 0;
  z-index: 2;
}

.file-icon {
  font-size: 32px;
  margin-right: 12px;
  flex-shrink: 0;
}

.file-container.grid .file-icon {
  font-size: 64px;
  margin-right: 0;
  margin-bottom: 16px;
}

/* 不同文件类型的颜色 */
.file-type-image {
  color: #52c41a; /* 绿色 - 图片 */
}

.file-type-video {
  color: #f5222d; /* 红色 - 视频 */
}

.file-type-audio {
  color: #fa8c16; /* 橙色 - 音频 */
}

.file-type-pdf {
  color: #eb2f96; /* 粉红色 - PDF */
}

.file-type-word {
  color: #2f54eb; /* 蓝色 - Word */
}

.file-type-excel {
  color: #13c2c2; /* 青色 - Excel */
}

.file-type-ppt {
  color: #fa541c; /* 深橙色 - PowerPoint */
}

.file-type-zip {
  color: #722ed1; /* 紫色 - 压缩包 */
}

.file-type-text {
  color: #595959; /* 灰色 - 文本 */
}

.file-type-default {
  color: #1890ff; /* 默认蓝色 */
}

.file-info {
  flex: 1;
  min-width: 0;
}

.file-container.grid .file-info {
  width: 100%;
}

.file-name {
  font-size: 14px;
  font-weight: 500;
  color: #262626;
  margin-bottom: 4px;
  word-break: break-all;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.file-container.grid .file-name {
  white-space: normal;
  word-break: break-word;
  margin-bottom: 12px;
  font-size: 15px;
  font-weight: 600;
  color: #1f1f1f;
  line-height: 1.5;
  max-height: 3em;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.file-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 12px;
  color: #8c8c8c;
  margin-bottom: 4px;
}

.file-container.grid .file-meta {
  flex-direction: column;
  gap: 6px;
  font-size: 13px;
  color: #999;
  margin-bottom: 8px;
}

.file-description {
  font-size: 12px;
  color: #595959;
  margin-bottom: 4px;
  word-break: break-all;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.file-container.grid .file-description {
  white-space: normal;
  word-break: break-word;
  font-size: 12px;
  color: #999;
  line-height: 1.6;
  max-height: 3.2em;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  margin-bottom: 12px;
}

.file-category {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: #1890ff;
}

.file-category span {
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-container.grid .file-category {
  position: absolute;
  top: 12px;
  right: 12px;
  padding: 4px 10px;
  background: linear-gradient(135deg, rgba(24, 144, 255, 0.1) 0%, rgba(24, 144, 255, 0.15) 100%);
  border-radius: 12px;
  display: inline-flex;
  font-size: 11px;
  font-weight: 500;
  z-index: 1;
  backdrop-filter: blur(8px);
  box-shadow: 0 2px 6px rgba(24, 144, 255, 0.15);
}

.file-container.grid .file-category span {
  max-width: 80px;
}

.file-category-inline {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: #1890ff;
  margin-top: 4px;
}

.file-category-inline span {
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-actions {
  flex-shrink: 0;
  margin-left: 8px;
}

.file-container.grid .file-actions {
  position: absolute;
  bottom: 0;
  right: 0;
}

.action-buttons-grid {
  display: flex;
  align-items: center;
  gap: 4px;
  border-radius: 10px;
}

.action-buttons-grid .ant-btn {
  border: none;
  box-shadow: none;
  width: 32px;
  height: 32px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: transparent;
  transition: all 0.2s;
}

.action-buttons-grid .ant-btn:hover {
  background: rgba(24, 144, 255, 0.1);
}

.pagination-container {
  display: flex;
  justify-content: center;
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid #f0f0f0;
}

.file-detail {
  padding: 16px 0;
}

.detail-row {
  display: flex;
  margin-bottom: 12px;
  align-items: flex-start;
}

.detail-label {
  font-weight: 500;
  color: #262626;
  min-width: 80px;
  flex-shrink: 0;
}

.detail-value {
  color: #595959;
  word-break: break-all;
}

.detail-actions {
  display: flex;
  gap: 12px;
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid #f0f0f0;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .file-toolbar {
    flex-direction: column;
    gap: 12px;
    align-items: stretch;
  }

  .toolbar-left,
  .toolbar-right {
    justify-content: center;
  }

  .batch-actions-bar {
    flex-direction: column;
    gap: 12px;
    align-items: stretch;
  }

  .batch-actions-left,
  .batch-actions-right {
    width: 100%;
    justify-content: space-between;
  }

  .file-container.grid {
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 16px;
  }

  .file-container.grid .file-item {
    padding: 20px 16px;
  }

  .file-container.grid .file-icon {
    font-size: 48px;
    margin-bottom: 12px;
  }

  .file-container.grid .file-name {
    font-size: 14px;
  }

  .file-container.grid .file-meta {
    font-size: 11px;
  }
}
</style>
